import json
from datetime import datetime

from django.db import transaction
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views import View
from rest_framework import status, exceptions, viewsets, mixins
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.oaauth.models import OADepartment, OAUser, UserStatus
from apps.oaauth.serializers import DepartmentSerializer, UserSerializer
from apps.staff.paginations import StaffPageNumberPagination
from apps.staff.serializers import AddStaffSerializer, ActiveStaffSerializer, StaffUploadSerializer
from apps.staff.utils import send_active_email

from oaback import settings
from utils import aeser
import pandas as pd
aes = aeser.AESCipher(settings.SECRET_KEY)


class Department(generics.ListAPIView):
    queryset = OADepartment.objects.all()
    serializer_class = DepartmentSerializer

class ActiveStaffView(View):
    def get(self, request):
        token = request.GET.get('token')
        response = render(request, 'active.html')
        response.set_cookie('token', token)
        return response

    def post(self, request):
        try:
            token = request.COOKIES.get('token')
            email = aes.decrypt(token)
            serializer = ActiveStaffSerializer(data=request.POST)
            if serializer.is_valid():
                form_email = serializer.data.get('email')
                user = serializer.data.get('user')
                if form_email != email:
                    return JsonResponse({'code': 400, "message": f"邮箱输入错误！"})
                user.status = True
                message = f"{user.realname}账户激活成功！"

                return JsonResponse({'code': 200, "message": message})
            else:
                detail = list(serializer.errors.values())[0]
                return JsonResponse({'code': 400, "message": f"{detail}"})
        except Exception as e:
            return JsonResponse({'code': 400, "message": "token错误"})

class StaffViewSet(
    viewsets.GenericViewSet,
    mixins.ListModelMixin,
    mixins.CreateModelMixin,
    mixins.UpdateModelMixin,
):
    queryset = OAUser.objects.all()
    pagination_class = StaffPageNumberPagination

    def get_serializer_class(self):
        if self.request.method in ['GET', 'PUT']:
            return UserSerializer
        else:
            return AddStaffSerializer

    def get_queryset(self):
        data = self.request.query_params
        department_id = data.get('department_id')
        realname = data.get('realname')
        date_joined = data.get('date_joined[]')

        queryset = self.queryset
        user = self.request.user
        if user.department.name != '董事会':
            if user.department.leader.uid != user.uid:
                raise exceptions.PermissionDenied
            else:
                queryset = queryset.filter(department_id=user.department_id)
        else:
            if department_id:
                queryset = queryset.filter(department_id=department_id)
        if realname:
            queryset = queryset.filter(realname__icontains=realname)
        if date_joined:
            try:
                start_date = datetime.strptime(date_joined[0], '%Y-%m-%d')
                end_date = datetime.strptime(date_joined[1], '%Y-%m-%d')
                queryset = queryset.filter(date_joined__range=(start_date, end_date))
            except Exception as e:
                pass
        return queryset.all()


    def create(self, request, *args, **kwargs):
        serializer = AddStaffSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            email = serializer.validated_data['email']
            realname = serializer.validated_data['realname']
            password = serializer.validated_data['password']
            telephone = serializer.validated_data['telephone']
            try:
                send_active_email(request, email, aes)
            except Exception as e:
                return Response(data={'detail': "发送邮箱验证失败"}, status=status.HTTP_400_BAD_REQUEST)
            user = OAUser.objects.create_user(email=email, realname=realname, password=password, telephone=telephone)
            department = request.user.department
            user.department = department
            user.save()
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(data={'detail':list(serializer.errors.values())}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return super().update(request, *args, **kwargs)


class StaffDownload(APIView):
    def get(self, request):
        pks = request.query_params.get('pks')
        if not pks:
            return Response(data={'detail': "请选择员工编号"}, status=status.HTTP_400_BAD_REQUEST)
        try:
            try:
                pks = json.loads(pks)
            except json.decoder.JSONDecodeError as e:
                return Response(data={'detail': "员工参数错误"}, status=status.HTTP_400_BAD_REQUEST)
            current_user = request.user
            queryset = OAUser.objects
            if current_user.department.name != '董事会':
                if current_user.department.leader.uid != current_user.uid:
                    return Response(data={"detail": "权限不足"}, status=status.HTTP_403_FORBIDDEN)
                else:
                    queryset = queryset.filter(department_id=current_user.department_id)
            queryset = queryset.filter(pk__in=pks)
            result = queryset.values("realname", "email", "telephone", "department__name", "date_joined", "status")
            user_staff = pd.DataFrame(list(result))
            staff_df = user_staff.rename(columns={"realname": "员工姓名",
                                                  "email": "邮箱",
                                                  "telephone": "手机号",
                                                  "date_joined": "入职日期",
                                                  "status": "状态",
                                                  "department__name":"部门名称"
                                                  })
            response = HttpResponse(content_type='application/xlsx')
            response['Content-Disposition'] = "attachment; filename=员工信息.xlsx"
            with pd.ExcelWriter(response) as writer:
                staff_df.to_excel(writer, sheet_name='员工信息')
            return response
        except Exception as e:
            return Response(data={'detail': f"下载错误{e}"}, status=status.HTTP_400_BAD_REQUEST)


class StaffUploadView(APIView):
    def post(self, request):
        serializer = StaffUploadSerializer(data=request.data)
        if serializer.is_valid():
            file = serializer.validated_data.get('file')
            current_user = request.user
            if current_user.department.leader.uid != current_user.uid or current_user.department.name != "董事会":
                return Response(data={'detail':"无权"}, status=status.HTTP_403_FORBIDDEN)
            staff_df = pd.read_excel(file)
            users = []
            for index, row in staff_df.iterrows():
                if current_user.department.name != "董事会":
                    department = current_user.department
                else:
                    try:
                        department = OADepartment.objects.filter(name=row['部门']).first()
                        if not department:
                            return Response(data={"detail": f"{row['部门']}部门不存在"}, status=status.HTTP_400_BAD_REQUEST)
                    except Exception as e:
                        return Response(data={"detail": f"部门列不存在"}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    email = row['邮箱']
                except Exception as e:
                    return Response(data={"detail": f"邮箱不存在"}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    realname = row['姓名']
                except Exception as e:
                    return Response(data={"detail": f"姓名不存在"}, status=status.HTTP_400_BAD_REQUEST)
                password = '111111'
                telephone = row['手机号']
                user = OAUser(email=email, realname=realname, telephone=telephone, status=UserStatus.UNACTIVATED, department=department)
                user.set_password(password)
                users.append(user)
            try:
                with transaction.atomic():
                    OAUser.objects.bulk_create(users)
            except Exception as e:
                return Response(data={'detail': "员工信息添加错误"}, status=status.HTTP_400_BAD_REQUEST)
            for user in users:
                send_active_email(request, user.email, aes)
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(data={'detail': list(serializer.errors.values())}, status=status.HTTP_400_BAD_REQUEST)